# -*- coding: utf-8 -*-

import os
from functools import wraps
from datetime import datetime, timedelta
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users
from tsbase import *
from tsmodel import *

formaction = ['addnew','modify','delete']

class Error404(baseHandler):
    def get(self,slug=None):
        return self.render('template/404.html', {})

class tiens_setup(baseHandler):
    @requires_admin
    def get(self):
        self.redirect("/tiens")

class tiens_move2gs(baseHandler):
    @requires_admin
    def get(self):
        rlimit = self.reqint('pagesize',10)
        picurl=[]
        try:
            pp = prodpic.all().fetch(rlimit)
            for p in pp:
                url = upload2gs(BUCKET_NAME, p.name, p.fbin, 'pf', mime_type=p.filetype)
                pr = prod.all().filter('picid =', p.key().id()).fetch(10)
                if pr:
                    for d in pr:
                        d.picurl= url
                        d.put()
                picurl.append( '<img src="%s">' % url )
        except:
            pass
        self.write("".join(picurl))

class tiens_prods(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')
        ropt = self.reqbool('opt')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = prod.all().order('code')

            rcode = self.req('pcode').upper()
            if rcode:
                qry.filter('code >=', rcode)
            rpvtype = self.req('pvtypename')
            if rpvtype and rpvtype != 'all':
                qry.filter('pvtype =', db.Key(rpvtype))

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                if ropt:
                    for dT in daTa:
                        dtkey=dT.key()
                        op.append(u'"%s": {"guid":"%s", "prod":"%s", "pcode":"%s", "pname":"%s", "unit":"%s", "price":"%s", "sepreport":"%s"}'%
                            (dT.code, dtkey, dtkey, dT.code, dT.name, dT.unit, dT.price, 'yes' if dT.sepreport else 'no' ))
                else:
                    for dT in daTa:
                        ppic = (u"<a href='/pp/%s' target='_blank'>查看</a>" % dT.picid) if dT.picid else u'无'
                        op.append(u'"%s": {"guid":"%s", "pcode":"%s", "pname":"%s","spec":"%s","pclass":"%s","pclassname":"%s","pvtype":"%s","pvtypename":"%s","unit":"%s","price":"%s","ppic":"%s","status":"%s","statuslbl":"%s", "sepreport":"%s"}'%
                            (dT.key(), dT.key(), dT.code, dT.name, dT.spec, dT.refcls.key() if dT.refcls else '', dT.refcls.name if dT.refcls else u'无', dT.pvtype.key() if dT.pvtype else '', dT.pvtype.name if dT.pvtype else u'无', dT.unit, dT.price, ppic, dT.status, {"active":u"正常","locked":u"锁定","soldout":u"断货","deprecated":u"弃用"}[dT.status], 'yes' if dT.sepreport else 'no' ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.render("template/prodset.html", {})

    @requires_admin
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?invalid action")

        if raction == 'delete':
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = prod.get(rkey)
                if DaTa:
                    msg.append( "%s=" % DaTa.key() )
                    DaTa.remove()
                    if loglog:
                        logging.warning("Admin_Log:%s %s(key:%s) detail(code:%s,name:%s,spec:%s,unit:%s,pvtype:%s,refcls:%s,price:%s,picid:%s,status:%s,sepreport:%s) by %s" %
                        (raction, DaTa.kind(), rkey, DaTa.code, DaTa.name, DaTa.spec, DaTa.unit, (str(DaTa.pvtype.key())+"|"+DaTa.pvtype.code+"|"+DaTa.pvtype.name) if DaTa.pvtype else None, (str(DaTa.refcls.key())+"|"+DaTa.refcls.code+"|"+DaTa.refcls.name) if DaTa.refcls else None, DaTa.price, DaTa.picid, DaTa.status, DaTa.sepreport, self.accEmail))
            if msg:
                #reset cache
                #getdata(prod, order=["code"], limit=300, reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error")

        rcode = self.req("pcode").upper()
        rname = self.req("pname")
        rspec = self.req("spec")
        runit = self.req("unit")
        rpvt = self.req("pvtype")
        rpcls = self.req("pclass")
        rprice = self.req("price")
        rstatus = self.req("status")
        rseprpt = self.reqbool("sepreport")

        rbin = self.req("fpic")

        if not rcode:
            return self.writeJsTry("alert('error!?code required');")
        if not rname:
            return self.writeJsTry("alert('error!?name required');")
        if not rspec:
            return self.writeJsTry("alert('error!?spec required');")
        if not runit:
            return self.writeJsTry("alert('error!?unit required');")
        if not rprice:
            return self.writeJsTry("alert('error!?price required');")
        if not rpvt:
            return self.writeJsTry("alert('error!?pvtype required');")

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = prod.get(rkey)
            if not DaTa:
                return self.writeJsTry("alert('error!?id not valid');")
            else:
                Ydata = prod.all().filter('code =', rcode).fetch(2)#最多应该只能取得1个结果
                if Ydata and Ydata[0].key()!=DaTa.key():
                    return self.writeJsTry("alert('error!?code exist');")

                DaTa.code = rcode
                DaTa.name = rname
                DaTa.spec = rspec
                DaTa.unit = runit
                DaTa.pvtype = pvtype.get(rpvt) if rpvt else None
                DaTa.refcls = prodcls.get(rpcls) if rpcls else None
                DaTa.price = float(rprice)
                DaTa.status = rstatus
                DaTa.sepreport = rseprpt

                DaTa.put()

                picid = DaTa.picid

        if raction == 'addnew':
            Ydata = prod.all().filter('code =', rcode).count(2)#最多应该只能取得1个结果
            if Ydata:
                return self.writeJsTry("alert('error!?code exist');")

            if not rbin:
                picid = None
            else:
                picname = unicode(self.request.body_file.vars['fpic'].filename,'utf-8')
                mime = self.request.body_file.vars['fpic'].headers['content-type']
                if mime not in ["image/png", "image/jpeg", "image/gif"]:
                    return self.writeJsTry("alert('error!?文件类型不正确！');parent.$('prods').reset();")
                if len(rbin)>1024*500:
                    return self.writeJsTry("alert('error!?文件大小超出500KB限制！');parent.$('prods').reset();")

                picid = prodpic.add(rcode, picname, mime, rname, rbin).key().id()
                #picurl = upload2gs(BUCKET_NAME, picname, rbin, folder='pf', mime_type=mime)

            DaTa = prod(
                    code = rcode,
                    name = rname,
                    spec = rspec,
                    unit = runit,
                    pvtype = pvtype.get(rpvt) if rpvt else None,
                    refcls = prodcls.get(rpcls) if rpcls else None,
                    price = float(rprice),
                    picid = picid,
                    #picurl = picurl,
                    status = rstatus,
                    sepreport = rseprpt
                    )

            DaTa.put()

            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(code:%s,name:%s,spec:%s,unit:%s,pvtype:%s,refcls:%s,price:%s,picid:%s,status:%s,sepreport:%s) by %s" %
            (raction, DaTa.kind(), rkey, rcode, rname, rspec, runit, rpvt, rpcls, rprice, picid, rstatus, rseprpt, self.accEmail))

        pclsname = DaTa.refcls.name if DaTa.refcls else u'无'
        pvtname = DaTa.pvtype.name if DaTa.pvtype else u'无'
        picid = DaTa.picid if DaTa.picid else u'无'
        ppic = (u'<a href="/pp/%s" target="_blank">查看</a>' % DaTa.picid) if DaTa.picid else u'无'
        statuslbl = {"active":u"正常","locked":u"锁定","soldout":u"断货","exitmarket":u"退市"}[rstatus]

        #reset cache
        #getdata(prod, order=["code"], limit=300, reset=True)

        self.writeJsTry(u"parent.oaform.form.reset();parent.dtprod.setBody({'%s':{'guid':'%s',pcode:'%s',pname:'%s',spec:'%s',unit:'%s',pvtype:'%s',pclass:'%s',pclassname:'%s',pvtypename:'%s',price:'%s',picid:'%s', ppic:'%s', status:'%s', statuslbl:'%s', sepreport:'%s'}}).pager();"%
                (rkey, rkey, rcode, rname, rspec, runit, rpvt if rpvt else '', rpcls if rpcls else '', pclsname, pvtname, rprice, picid, ppic, rstatus, statuslbl, 'yes' if rseprpt else 'no'))
#        self.write(u"success!?{'%s':{'guid':'%s',pcode:'%s',pname:'%s',spec:'%s',unit:'%s',pvtype:'%s',pclass:'%s',pclassname:'%s',pvtypename:'%s',price:'%s',picid:'%s', ppic:'%s', status:'%s', statuslbl:'%s', sepreport:'%s'}}"%
#                (rkey, rkey, rcode, rname, rspec, runit, rpvt if rpvt else '', rpcls if rpcls else '', pclsname, pvtname, rprice, picid, ppic, rstatus, statuslbl, 'yes' if rseprpt else 'no'))

class tiens_pvtype(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = pvtype.all().order('-pvrate').order('-bvrate').order('code')

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "ptcode":"%s", "ptname":"%s","ratepv":"%s","pvrate":"%s","bvrate":"%s","locked":"%s","lockin":"%s"}'%
                        (dT.key(), dT.key(), dT.code, dT.name, dT.ratepv, dT.pvrate, dT.bvrate, 'yes' if dT.locked else 'no', '&#10008;' if dT.locked else '&#10004;' ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authadmin_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?invalid action")

        if raction == 'delete':
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = pvtype.get(rkey)
                if DaTa:
                    if not DaTa.pvprod.count(2):#有该类型产品时不能删除
                        msg.append("%s=" % DaTa.key() )
                        DaTa.delete()
                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(code:%s,name:%s,ratepv:%s,pvrate:%s,bvrate:%s,locked:%s) by %s" %
                            (raction, DaTa.kind(), rkey, DaTa.code, DaTa.name, DaTa.ratepv, DaTa.pvrate, DaTa.bvrate, DaTa.locked, self.accEmail))
            if msg:
                #reset cache
                pubdata(pvtype, order=["-pvrate","-bvrate","code"], reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?used")

        rcode = self.req("ptcode").upper()
        rname = self.req("ptname")
        rrate = self.reqrate("ratepv")
        rpv = self.reqrate("pvrate")
        rbv = self.reqrate("bvrate")
        rlock = self.reqbool("locked")

        if not rcode:
            return self.write('error!?code required')
        if not rname:
            return self.write('error!?name required')

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = pvtype.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                if rcode:
                    Ydata = pvtype.all().filter('code =', rcode).fetch(2)
                    if Ydata and Ydata[0].key()!=DaTa.key():
                        return self.write('error!?code exist')

                DaTa.code = rcode
                DaTa.name = rname
                DaTa.ratepv = rrate
                DaTa.pvrate = rpv
                DaTa.bvrate = rbv
                DaTa.locked = rlock

                DaTa.put()

        if raction == 'addnew':
            Ydata = pvtype.all().filter('code =', rcode).count(2)
            if Ydata:
                return self.write('error!?code exist')

            DaTa = pvtype(code = rcode,
                name = rname,
                ratepv = rrate,
                pvrate = rpv,
                bvrate = rbv,
                locked = rlock)
            DaTa.put()
            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(code:%s,name:%s,ratepv:%s,pvrate:%s,bvrate:%s,locked:%s) by %s" %
            (raction, DaTa.kind(), rkey, rcode, rname, rrate, rpv, rbv, rlock, self.accEmail))

        #reset cache
        pubdata(pvtype, order=["-pvrate","-bvrate","code"], reset=True)

        return self.write(u"success!?guid:%s;ptcode:%s;ptname:%s;ratepv:%s;pvrate:%s;bvrate:%s;locked:%s;lockin:%s" %
                (rkey, rcode, rname, rrate, rpv, rbv, 'yes' if rlock else 'no', '&#10008;' if rlock else '&#10004;' ))

class tiens_pclass(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = prodcls.all()

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "clscode":"%s", "clsname":"%s","refcls":"%s","refclscode":"%s","clscss":"%s"}'%
                        (dT.key(), dT.key(), dT.code, dT.name, dT.refcls.key() if dT.refcls else '', dT.refcls.code if dT.refcls else u'无', dT.csstyle ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authadmin_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?invalid action")

        if raction == 'delete':
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = prodcls.get(rkey)
                if DaTa:
                    if not (DaTa.subcls.count(2) or DaTa.clsprod.count(2)):#有下级类别，或有该类别产品时不能删除
                        msg.append( "%s=" % DaTa.key() )
                        DaTa.delete()
                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(refcls:%s,code:%s,name:%s,csstyle:%s) by %s" %
                            (raction, DaTa.kind(), rkey, (str(DaTa.refcls.key())+"|"+DaTa.refcls.code+"|"+DaTa.refcls.name) if DaTa.refcls else None, DaTa.code, DaTa.name, DaTa.csstyle, self.accEmail))
            if msg:
                #reset cache
                #pubdata(prodcls, order=["code"], reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?in use")

        rcls = self.req("refcls")
        rcode = self.req("clscode").upper()
        rname = self.req("clsname")
        rcss = self.req("clscss").lower()

        if not rcode:
            return self.write('error!?code required')
        if not rname:
            return self.write('error!?name required')

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = prodcls.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                DaTa.refcls = prodcls.get(rcls) if rcls else None
                DaTa.code = rcode
                DaTa.name = rname
                DaTa.csstyle = rcss

                DaTa.put()

        if raction == 'addnew':
            Ydata = prodcls.all().filter('code =', rcode).count(2)
            if Ydata:
                return self.write('error!?code exist')

            DaTa = prodcls(
                    refcls = prodcls.get(rcls) if rcls else None,
                    code = rcode,
                    name = rname,
                    csstyle = rcss
                    )
            DaTa.put()

            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(refcls:%s,code:%s,name:%s,csstyle:%s) by %s" %
            (raction, DaTa.kind(), rkey, rcls, rcode, rname, rcss, self.accEmail))

        #reset cache
        #pubdata(prodcls, order=["code"], reset=True)

        refclscode = DaTa.refcls.code if DaTa.refcls else u'无'
        return self.write(u"success!?guid=%s&clscode=%s&clsname=%s&refcls=%s&refclscode=%s&clscss=%s" %
            (rkey, rcode, rname, rcls if rcls else '', refclscode, rcss))

class tiens_vips(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')
        ropt = self.reqbool('opt')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')
            rbydate = self.req('jmonth')

            if rbydate=='later':
                qry = vip.all().order('-apldate').order('idcard')
            elif rbydate=='earlier':
                qry = vip.all().order('apldate').order('idcard')
            elif rbydate=='outearlier':
                qry = vip.all().order('-apldate').filter('apldate <', datetime(2009,11,1).date()).order('idcard')
            elif rbydate:
                qry = vip.all().filter('apldate =', datetime.strptime(rbydate,"%Y-%m").date().replace(day=20)).order('idcard')
            else:
                qry = vip.all().order('idcard')

            rvipid = self.req('vipid').upper()
            if rvipid:
                qry = vip.all().order('idcard').filter('idcard >=', rvipid)

            rfn = self.req('vip_name')
            if rfn:
                qry.filter('vipname =', rfn)

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                if ropt:
                    for dT in daTa:
                        dtkey=dT.key()
                        #vipname for sale opt, vip_name for vip list
                        op.append(u'"%s": {"guid":"%s", "vip":"%s", "refvip":"%s", "vipid":"%s", "refvipid":"%s", "vipname":"%s", "vip_name":"%s"}'%
                            (dT.idcard, dtkey, dtkey, dtkey, dT.idcard, dT.idcard, dT.vipname, dT.vipname ))
                else:
                    for dT in daTa:
                        #uname for addnew/edit, vip_name for vip list
                        op.append(u'"%s": {"guid":"%s", "refcomp":"%s", "refstore":"%s","refvip":"%s","refvipname":"%s","refvipid":"%s","vipid":"%s","idcard":"%s","uname":"%s","vip_name":"%s","gender":"%s","jdate":"%s","jmonth":"%s","phone":"%s","mobile":"%s","vipcard":"%s","vipcardsn":"%s"}'%
                            (dT.key(), dT.key(), dT.refcmpny.key() if dT.refcmpny else '', dT.refstore.key() if dT.refstore else '', dT.refvip.key() if dT.refvip else '', dT.refvip.vipname if dT.refvip else u'无', dT.refvip.idcard if dT.refvip else u'无', dT.idcard, dT.idcard, dT.vipname, dT.vipname, 'yes' if dT.gender else 'no', dT.apldate if dT.apldate else '', dT.apldate.strftime('%Y-%m') if dT.apldate else u'无', dT.phone, dT.mobile, dT.vipcard, dT.vipcardsn ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("success!?{}")

    @authorized_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?action invalid")

        if raction == 'delete':#@todo:应慎重删除，被取消账户顾客链也须更新
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = vip.get(rkey)
                if DaTa:
                    if not DaTa.subvip.count(2):
                        msg.append( "%s=" % DaTa.key() )
                        DaTa.delete()
                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(refcmpny:%s,refstore:%s,refvip:%s,apldate:%s,idcard:%s,vipname:%s,gender:%s,phone:%s,mobile:%s,vipcard:%s,vipcardsn:%s) by %s" %
                            (raction, DaTa.kind(), rkey, (str(DaTa.refcmpny.key())+"|"+DaTa.refcmpny.code+"|"+DaTa.refcmpny.name) if DaTa.refcmpny else None, (str(DaTa.refstore.key())+"|"+DaTa.refstore.code+"|"+DaTa.refstore.name) if DaTa.refstore else None, (str(DaTa.refvip.key())+"|"+DaTa.refvip.idcard+"|"+DaTa.refvip.vipname) if DaTa.refvip else None, DaTa.apldate, DaTa.idcard, DaTa.vipname, DaTa.gender, DaTa.phone, DaTa.mobile, DaTa.vipcard, DaTa.vipcardsn, self.accEmail))
            if msg:
                #reset cache
                #getdata(vip, order=['-apldate', "idcard"], limit=500, reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?can not delete!")

        rrefc = self.req("refcomp")
        rrefs = self.req("refstore")
        rdate = self.req("jdate")
        rrefvip = self.req("refvip")
        ridcard = self.req("idcard").upper()
        rname = self.req("uname")
        rgender = self.reqbool("gender")
        rphone = self.req("phone")
        rmobile = self.req("mobile")
        rvipcard = self.req("vipcard")
        rvipcardsn = self.req("vipcardsn")

        if not ridcard:
            return self.write('error!?idcard required')
        if not rname:
            return self.write('error!?vipname required')

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = vip.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                if ridcard:
                    Ydata = vip.all().filter('idcard =', ridcard).fetch(2)#最多应该只能取得1个结果
                    if Ydata and Ydata[0].key()!=DaTa.key():
                        return self.write('error!?idcard exist')
                if rrefvip:
                    rvip = vip.get(rrefvip)
                    if rvip.idcard == ridcard:
                        return self.write('error!?idcard error..')#介绍人不能是自己

                DaTa.refcmpny = cstore.get(rrefc) if rrefc else None
                DaTa.refstore = cstore.get(rrefs) if rrefs else None
                DaTa.refvip = vip.get(rrefvip) if rrefvip else None
                DaTa.apldate = datetime.strptime(rdate,"%Y-%m-%d").date().replace(day=20) if rdate else None
                DaTa.idcard = ridcard
                DaTa.vipname = rname
                DaTa.gender = rgender
                DaTa.phone = rphone
                DaTa.mobile = rmobile
                DaTa.vipcard = rvipcard
                DaTa.vipcardsn = rvipcardsn

                DaTa.put()

        if raction == 'addnew':
            Ydata = vip.all().filter('idcard =', ridcard).count(2)#最多应该只能取得1个结果
            if Ydata:
                return self.write('error!?idcard exist')

            DaTa = vip(
                    refcmpny = cstore.get(rrefc) if rrefc else None,
                    refstore = cstore.get(rrefs) if rrefs else None,
                    refvip = vip.get(rrefvip) if rrefvip else None,
                    apldate = datetime.strptime(rdate,"%Y-%m-%d").date().replace(day=20) if rdate else None,
                    idcard = ridcard,
                    vipname = rname,
                    gender = rgender,
                    phone = rphone,
                    mobile = rmobile,
                    vipcard = rvipcard,
                    vipcardsn = rvipcardsn
                    )
            DaTa.put()

            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(refcmpny:%s,refstore:%s,refvip:%s,apldate:%s,idcard:%s,vipname:%s,gender:%s,phone:%s,mobile:%s,vipcard:%s,vipcardsn:%s) by %s" %
            (raction, DaTa.kind(), rkey, rrefc, rrefs, rrefvip, rdate, ridcard, rname, rgender, rphone, rmobile, rvipcard, rvipcardsn, self.accEmail))

        refvipname = "%s" % DaTa.refvip.vipname if DaTa.refvip else u'无'
        refvipid = "%s" % DaTa.refvip.idcard if DaTa.refvip else u'无'
        jmonth = DaTa.apldate.strftime('%Y-%m') if DaTa.apldate else u'无'
        rdate = DaTa.apldate.strftime('%Y-%m-%d') if DaTa.apldate else ''

        #reset cache
        #getdata(vip, order=['-apldate', "idcard"], limit=500, reset=True)

        return self.write(u"success!?&guid=%s&refcomp=%s&refstore=%s&refvip=%s&refvipname=%s&refvipid=%s&vipid=%s&idcard=%s&uname=%s&vip_name=%s&gender=%s&jdate=%s&jmonth=%s&phone=%s&mobile=%s&vipcard=%s&vipcardsn=%s" %
                (rkey, rrefc, rrefs, rrefvip, refvipname, refvipid, ridcard, ridcard, rname, rname, 'yes' if rgender else 'no', rdate, jmonth, rphone, rmobile, rvipcard, rvipcardsn))

class tiens_cstore(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = cstore.all()

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "atype":"%s", "regref":"%s","refcode":"%s","acode":"%s","aname":"%s","owner":"%s","addr":"%s","postcode":"%s","phone":"%s","mobile":"%s","refpo":"%s"}'%
                        (dT.key(), dT.key(), dT.type, dT.regref.key() if dT.regref else '', dT.regref.code if dT.regref else u'无', dT.code, dT.name, dT.owner.key() if dT.owner else '', dT.addr, dT.postcode, dT.phone, dT.mobile, dT.refpo.key() if dT.refpo else '' ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authadmin_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?action invalid")

        if raction == 'delete':
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = cstore.get(rkey)
                if DaTa:
                    if not ( DaTa.branch.count(2) or DaTa.companyvip.count(2) or DaTa.storevip.count(2) ):
                        msg.append("%s=" % DaTa.key() )
                        DaTa.delete()
                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(regref:%s,type:%s,code:%s,name:%s,owner:%s,addr:%s,postcode:%s,phone:%s,mobile:%s,refpo:%s) by %s" %
                            (raction, DaTa.kind(), rkey, (str(DaTa.regref.key())+"|"+DaTa.regref.code+"|"+DaTa.regref.name) if DaTa.regref else None, DaTa.type, DaTa.code, DaTa.name, (str(DaTa.owner.key())+"|"+DaTa.owner.email+"|"+DaTa.owner.name) if DaTa.owner else None, DaTa.addr, DaTa.postcode, DaTa.phone, DaTa.mobile, (str(DaTa.refpo.key())+"|"+DaTa.refpo.code+"|"+DaTa.refpo.name) if DaTa.refpo else None, self.accEmail))
            if msg:
                #reset cache
                try:
                    memcache.delete_multi(['optcmpny','optstore'])
                except:
                    pass
                #pubdata(cstore, order=["code"], reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?in use")

        rtype = self.req("atype").lower()
        rref = self.req("regref")
        rcode = self.req("acode").upper()
        rname = self.req("aname")
        rowner = self.req("owner")
        raddr = self.req("addr")
        rpostcode = self.req("postcode")
        rphone = self.req("phone")
        rmobile = self.req("mobile")
        rrefpo = self.req("refpo")

        if not rcode:
            return self.write('error!?cstore code required')
        if not rtype:
            return self.write('error!?cstore type required')
        if not rname:
            return self.write('error!?cstore name required')

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = cstore.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                if rcode:
                    Ydata = cstore.all().filter('code =', rcode).fetch(2)#最多应该只能取得1个结果
                    if Ydata and Ydata[0].key()!=DaTa.key():
                        return self.write('error!?cstore code exist')

                DaTa.regref = cstore.get(rref) if rref else None
                DaTa.owner = admin.get(rowner) if rowner else None
                DaTa.refpo = cstore.get(rrefpo) if rrefpo else None
                DaTa.type = 'ab' if rtype not in ['ca','cb','aa','ab'] else rtype
                DaTa.code = rcode
                DaTa.name = rname
                DaTa.addr = raddr
                DaTa.postcode = rpostcode
                DaTa.phone = rphone
                DaTa.mobile = rmobile

                DaTa.put()

        if raction == 'addnew':
            Ydata = cstore.all().filter('code =', rcode).count(2)#最多应该只能取得1个结果
            if Ydata:
                return self.write('error!?cstore exist')

            DaTa = cstore(
                    regref = cstore.get(rref) if rref else None,
                    type = 'ab' if rtype not in ['ca','cb','aa','ab'] else rtype,
                    code = rcode,
                    name = rname,
                    owner = admin.get(rowner) if rowner else None,
                    addr = raddr,
                    postcode = rpostcode,
                    phone = rphone,
                    mobile = rmobile,
                    refpo = cstore.get(rrefpo) if rrefpo else None
                    )
            DaTa.put()

            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(regref:%s,type:%s,code:%s,name:%s,owner:%s,addr:%s,postcode:%s,phone:%s,mobile:%s,refpo:%s) by %s" %
            (raction, DaTa.kind(), rkey, rref, rtype, rcode, rname, rowner, raddr, rpostcode, rphone, rmobile, rrefpo, self.accEmail))
        atype = DaTa.type
        refcode = DaTa.regref.code if DaTa.regref else u'无'

        #reset cache
        try:
            memcache.delete_multi(['optcmpny','optstore'])
        except:
            pass
        #pubdata(cstore, order=["code"], reset=True)

        return self.write(u"success!?&guid=%s&atype=%s&regref=%s&refcode=%s&acode=%s&aname=%s&owner=%s&addr=%s&postcode=%s&phone=%s&mobile=%s&refpo=%s" %
                (rkey, atype, rref, refcode, rcode, rname, rowner, raddr, rpostcode, rphone, rmobile, rrefpo))

class tiens_got(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')
        rreq = self.req('req')
        if rreq=='pvterm':
            isotime = (datetime.now()+timedelta(hours=+8)).isoformat()

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = stock.all().order('prodcode')

            rcode = self.req('pcode').upper()
            if rcode:
                qry.filter('prodcode >=', rcode)
            rpvtype = self.req('pvtypename')
            if rpvtype and rpvtype != 'all':
                qry.filter('pvtype =', db.Key(rpvtype))

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    p=dT.prod
                    op.append(u'"%s": {"guid":"%s", "pcode":"%s", "pname":"%s","spec":"%s","pvtype":"%s","pvtypename":"%s","unit":"%s","price":"%s","ppic":"<a href=\'/pp/%s\' target=\'_blank\'>查看</a>","qty":"%s"}'%
                        (dT.key(), dT.key(), p.code, p.name, p.spec, p.pvtype.key() if p.pvtype else '', p.pvtype.name if p.pvtype else u'无', p.unit, p.price, p.picid, dT.qty ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")
class tiens_stocks(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = stock.all().order('prodcode')

            rcode = self.req('pcode').upper()
            if rcode:
                qry.filter('prodcode >=', rcode)
            rpvtype = self.req('pvtypename')
            if rpvtype and rpvtype != 'all':
                qry.filter('pvtype =', db.Key(rpvtype))

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    p=dT.prod
                    op.append(u'"%s": {"guid":"%s", "pcode":"%s", "pname":"%s","spec":"%s","pvtype":"%s","pvtypename":"%s","unit":"%s","price":"%s","ppic":"<a href=\'/pp/%s\' target=\'_blank\'>查看</a>","qty":"%s"}'%
                        (dT.key(), dT.key(), p.code, p.name, p.spec, p.pvtype.key() if p.pvtype else '', p.pvtype.name if p.pvtype else u'无', p.unit, p.price, p.picid, dT.qty ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")
class tiens_cstorepv(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = pvstock.all().order('pvcode')

            if not self.adminacc:
                qry.filter('refcstore =', self.authacc.refcstore)

            mycskey = self.authacc.refcstore.key()
            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                def strdict(dic):
                    a=[]
                    for k,v in dic.items():
                        a.append('"%s":"%s"'% (k, v))
                    return ','.join(a)

                cspv={}
                for dT in daTa:
                    cspv[mycskey+dT.pvterm][dT.pvcode]=dT.amount
                for kpv, vpv in cspv.items():
                    op.append('"%s":{%s}'% (kpv, strdict(vpv)))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

class tiens_po(baseHandler):
    @authorized_ajax
    def get(self):
        return self.write(u'进货单功能稍后开放')
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = purorder.all().order('-orderno')

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    p=dT.prod
                    vip=dT.vip
                    op.append(u'"%s": {"guid":"%s", "vipname":"%s%s", "vipid":"%s","date":"%s","prod":"%s","prodname":"%s","prodcode":"%s","unit":"%s","price":"%s","qty":"%s","amount":"%s","pv":"%s","bv":"%s"}'%
                        (dT.key(), dT.key(), vip.lastname, vip.firstname, vip.idcard, dT.date, p.key(), p.name, p.code, p.unit, dT.price, dT.qty, dT.amount, dT.pv, dT.bv ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

class tiens_vipspv(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = vipvsales.all().filter('amount >', 0.0)
            if not self.adminacc:
                qry.filter('refcstore =', self.authacc.refcstore)

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    vip=dT.vip
                    op.append(u'"%s": {"guid":"%s", "vip":"%s", "vipname":"%s%s", "vipid":"%s","pvtypename":"%s","amount":"%s","pv":"%s","bv":"%s"}'%
                        (dT.key(), dT.key(), vip.key(), vip.lastname, vip.firstname, vip.idcard, dT.pvtype.name, dT.amount, dT.pv, dT.bv ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

class tiens_approvepvsall(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = vipvsales.all().filter('amount >', 0.0)
            if not self.adminacc:
                qry.filter('refcstore =', self.authacc.refcstore)

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    vip=dT.vip
                    op.append(u'"%s": {"guid":"%s", "vip":"%s", "vipname":"%s%s", "vipid":"%s","pvtypename":"%s","amount":"%s","pv":"%s","bv":"%s"}'%
                        (dT.key(), dT.key(), vip.key(), vip.lastname, vip.firstname, vip.idcard, dT.pvtype.name, dT.amount, dT.pv, dT.bv ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authorized_ajax
    def post(self):
        rallspv = self.reqbool('allvipspv')
        rappv = self.reqbool('approve')
        if not rappv or not rallspv:
            self.write("error!?action invalid!")
        rterm = self.req("pvterm")
        if not rterm:
            self.write("error!?pvterm required!")
        rterm = datetime.strptime(rterm,"%Y-%m").date().replace(day=24)


class tiens_pvreport(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = pvreport.all().order('-pvterm')
            if not self.adminacc:
                qry.filter('refcstore =', self.authacc.refcstore)

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "refstore":"%s", "date":"%s", "pvterm":"%s","amount":"%s","pv":"%s","bv":"%s"}'%
                        (dT.key(), dT.key(), dT.refcstore.key(), dT.date, dT.pvterm, dT.amount, dT.pv, dT.bv ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

class tiens_salesbill(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = salesbill.all().order('-date').order('vipid')
            if not self.adminacc:
                qry.filter('refcstore =', self.authacc.refcstore)

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "vip":"%s", "vipname":"%s", "vipid":"%s","date":"%s","bqty":"%s","bamount":"%s"}'%
                        (dT.key(), dT.key(), dT.vip.key(), dT.vipname, dT.vipid, dT.date, dT.qty, dT.amount ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authorized_ajax
    def post(self):
        """

        """
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?action invalid")

        if raction == 'delete':#@todo:业绩已报单不可删除，有足够可报业绩返回才可删除
            rkey = self.reqall("guid")
            msg = []
            rDaTa = salesbill.get(rkey)
            if rDaTa:
                for DaTa in rDaTa:
                    sDaTa = DaTa.sales_set.fetch(1000)
                    if sDaTa:
                        xdata = []
                        xkeys = []
                        xamt = {}
                        xerr = 0
                        for sdt in sDaTa:
                            dtcs = sdt.refcstore
                            dtp = sdt.prod
                            septag = dtp.code if dtp.sepreport else ''
                            dtpvt = dtp.pvtype
                            dtvip = sdt.vip
                            dtpvs = vipvsales.all().filter('vip =', dtvip).filter('refcstore =', dtcs).filter('pvtype =', dtpvt).filter('septag =', septag).get()
                            if dtpvs:
                                xkey = dtpvs.key().__str__()
                                if xkey in xkeys:
                                    xamt[xkey] = round(xamt[xkey]-sdt.amount, 5)
                                    xamt[xkey+'pv'] = round(xamt[xkey+'pv']-sdt.pv, 5)
                                    xamt[xkey+'bv'] = round(xamt[xkey+'bv']-sdt.bv, 5)
                                else:
                                    xamt[xkey] = round(dtpvs.amount-sdt.amount, 5)
                                    xamt[xkey+'pv'] = round(dtpvs.pv-sdt.pv, 5)
                                    xamt[xkey+'bv'] = round(dtpvs.bv-sdt.bv, 5)
                                    xkeys.append( xkey )
                                if xamt[xkey] >= 0.0:
                                    xdata.append( sdt )
                                else:
                                    xerr+=1
                            else:
                                xerr+=1
                        if xerr==0 and len(xdata)==len(sDaTa):
                            for xdt in xdata:
                                xdt.delete()
                                if loglog:
                                    logging.warning("Admin_Log:%s %s(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,idcard:%s,date:%s,prod:%s|%s|%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                                    (raction, xdt.kind(), xdt.key(), dtcs.key(), dtcs.code, dtcs.name, xdt.vip.key(), xdt.vipname, xdt.vipid, xdt.date, xdt.prod.key(), xdt.prodcode, xdt.prodname, xdt.price, xdt.qty, xdt.amount, xdt.pv, xdt.bv, self.accEmail))
                            for xkey in xkeys:
                                pvd = db.get(xkey)
                                ypv = pvd.pv
                                ybv = pvd.bv
                                yamt = pvd.amount
                                pvd.pv = xamt[xkey+'pv']
                                pvd.bv = xamt[xkey+'bv']
                                pvd.amount = xamt[xkey]
                                pvd.put()
                                if loglog:
                                    logging.debug("Admin_Log:modify- vipvsales(key:%s) detail(refcstore:%s%s|%s|%s,vip:%s|%s,idcard:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
                                    (xkey, dtcs.key(), dtcs.code, dtcs.name, dtvip.key(), dtvip.lastname, dtvip.firstname, dtvip.idcard, dtpvt.key(), dtpvt.code, round(pvd.pv-ypv, 5), round(pvd.bv-ybv, 5), round(pvd.amount-yamt, 5), septag, self.accEmail))

                            DaTa.delete()
                            dkey = DaTa.key()
                            msg.append( "%s=" % dkey )

                            if loglog:
                                logging.warning("Admin_Log:%s %s(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,date:%s,qty:%s,amount:%s) by %s" %
                                (raction, DaTa.kind(), dkey, DaTa.refcstore.key(), DaTa.refcstore.code, DaTa.refcstore.name, DaTa.vip.key(), DaTa.vipname, DaTa.vipid, DaTa.date, DaTa.qty, DaTa.amount, self.accEmail))
            if msg:
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?can not delete!")

        if raction == 'modify':
            bkey = self.req("guid")
            bDaTa = salesbill.get(bkey)
            if not bDaTa:
                return self.write("error!?id not valid")
        rdate = self.req("date")
        rvip = self.req("vip")
        rprod = self.reqall("prod")
        rqty = self.reqallint("qty", default=1)

        if not rdate:
            return self.write('error!?date required')
        if not rvip:
            return self.write('error!?vip required')
        if not rprod:
            return self.write('error!?prod required')
        if not rqty:
            return self.write('error!?qty required')

        dvip = vip.get(rvip)
        if not dvip:
            return self.write('error!?vip invalid')
        vipid = dvip.idcard
        vipname = '%s%s' % (dvip.lastname, dvip.firstname)
        refstore = self.authacc.refcstore

        ddate = datetime.strptime(rdate,"%Y-%m-%d").date()
        if not ddate:
            return self.write('error!?date invalid')
        if len(rprod)!=len(rqty):
            return self.write('error!?prod and qty not match!')
        bamt = []
        bqty = []
        if raction == 'modify':
            nprod = {}
            nqty = {}
            for z in range(len(rprod)):
                skey = self.req(rprod[z])
                if skey:
                    nprod[skey] = rprod[z]
                if rprod[z] in nqty:
                    nqty[rprod[z]] += rqty[z]
                else:
                    nqty[rprod[z]] = rqty[z]
            sDaTa = sales.all().filter('refsalesbill =', bDaTa).fetch(1000)
            for sdt in sDaTa:
                skey = sdt.key().__str__()
                if skey in nprod:
                    sqty = sdt.qty
                    mqty = nqty[nprod[skey]]
                    del nqty[nprod[skey]]
                    if sqty == mqty:
                        bamt.append(sdt.amount)
                        bqty.append(sdt.qty)
                        continue
                    else:
                        vprod = sdt.prod
                        septag = vprod.code if vprod.sepreport else ''
                        dtpvt = vprod.pvtype
                        vDaTa = vipvsales.all().filter('vip =', dvip).filter('refcstore =', refstore).filter('pvtype =', dtpvt).filter('septag =', septag).get()
                        if not vDaTa:
                            bamt.append(sdt.amount)
                            bqty.append(sdt.qty)
                            continue
                        elif sqty > mqty:
                            vqty = sqty-mqty
                            vamt = round(sdt.price*vqty, 5)
                            if vDaTa.amount<vamt:
                                bamt.append(sdt.amount)
                                bqty.append(sdt.qty)
                                #todo: 记住此项，等全部更新后重新算过
                                continue
                            vDaTa.amount = round(vDaTa.amount - vamt, 5)
                            vDaTa.pv = round(vDaTa.pv - sdt.pv*vqty/sqty, 5)
                            vDaTa.bv = round(vDaTa.bv - sdt.bv*vqty/sqty, 5)
                            vDaTa.put()
                            #loglog
                            if loglog:
                                logging.debug("Admin_Log:modify- vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,vipid:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
                                (vDaTa.key(), refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, dtpvt.key(), dtpvt.code, -round(sdt.pv*vqty/sqty, 5), -round(sdt.bv*vqty/sqty, 5), -vamt, septag, self.accEmail))
                            sdt.date = ddate
                            sdt.qty = mqty
                            sdt.amount = round(sdt.price*mqty, 5)
                            sdt.pv = round(sdt.pv*mqty/sqty, 5)
                            sdt.bv = round(sdt.bv*mqty/sqty, 5)
                            sdt.put()
                            bamt.append(sdt.amount)
                            bqty.append(sdt.qty)
                            if loglog:
                                logging.debug("Admin_Log:modify- sales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,vipid:%s,date:%s,prod:%s|%s|%s,unit:%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                                ( skey, refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, rdate, vprod.key(), vprod.code, vprod.name, sdt.unit, sdt.price, vqty, vamt, round(sdt.pv*vqty/sqty, 5), round(sdt.bv*vqty/sqty, 5), self.accEmail))
                        else:
                            vqty = mqty-sqty
                            vamt = round(sdt.price*vqty, 5)
                            vDaTa.amount = round(vDaTa.amount + vamt, 5)
                            vDaTa.pv = round(vDaTa.pv + sdt.pv*vqty/sqty, 5)
                            vDaTa.bv = round(vDaTa.bv + sdt.bv*vqty/sqty, 5)
                            vDaTa.put()
                            #loglog
                            if loglog:
                                logging.debug("Admin_Log:modify+ vipvsales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,vipid:%s,pvtype:%s|%s,pv:%s,bv:%s,amount:%s,septag:%s) by %s" %
                                (vDaTa.key(), refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, dtpvt.key(), dtpvt.code, -round(sdt.pv*vqty/sqty, 5), -round(sdt.bv*vqty/sqty, 5), -vamt, septag, self.accEmail))
                            sdt.date = ddate
                            sdt.qty = mqty
                            sdt.amount = round(sdt.price*mqty, 5)
                            sdt.pv = round(sdt.pv*mqty/sqty, 5)
                            sdt.bv = round(sdt.bv*mqty/sqty, 5)
                            sdt.put()
                            bamt.append(sdt.amount)
                            bqty.append(sdt.qty)
                            if loglog:
                                logging.debug("Admin_Log:modify+ sales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,idcard:%s,date:%s,prod:%s|%s|%s,unit:%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                                ( skey, refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, rdate, vprod.key(), vprod.code, vprod.name, sdt.unit, sdt.price, vqty, vamt, round(sdt.pv*vqty/sqty, 5), round(sdt.bv*vqty/sqty, 5), self.accEmail))
                elif not sdt.remove():
                    bamt.append(sdt.amount)
                    bqty.append(sdt.qty)
                else:
                    if loglog:
                        logging.debug("Admin_Log:delete sales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,idcard:%s,date:%s,prod:%s|%s|%s,unit:%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                        ( sdt.key(), sdt.refcstore.key(), sdt.refcstore.code, sdt.refcstore.name, sdt.vip, sdt.vipname, sdt.vipid, sdt.date, sdt.prod.key(), sdt.prodcode, sdt.prodname, sdt.unit, sdt.price, sdt.qty, sdt.amount, sdt.pv, sdt.bv, self.accEmail))

            for pkey, pqty in nqty.items():
                dprod = prod.get(pkey)
                if not dprod:
                    continue
                rprice = dprod.price
                ramt = round(pqty*rprice, 5)

                bamt.append(ramt)
                bqty.append(pqty)

                pcode = dprod.code
                pname = dprod.name
                punit = dprod.unit
                rpvt = dprod.pvtype
                pvtname = rpvt.name
                septag = pcode if dprod.sepreport else ''
                rpv = round(ramt*rpvt.ratepv*rpvt.pvrate/10000, 5)
                rbv = round(rpv*rpvt.bvrate/100, 5)

                DaTa = sales(
                    refsalesbill = bDaTa.key(),
                    refcstore = refstore,
                    vip = dvip,
                    vipid = vipid,
                    vipname = vipname,
                    date = ddate,
                    prod = dprod,
                    prodcode = pcode,
                    prodname = pname,
                    pvtypename = pvtname,
                    unit = punit,
                    qty = pqty,

                    price = rprice,
                    amount = ramt,
                    pv = rpv,
                    bv = rbv
                    )
                vipvsales.modify1(refstore, dvip, rpvt, rpv, rbv, ramt, septag)
                DaTa.put()

                rkey = DaTa.key()

                if loglog:
                    logging.debug("Admin_Log:addnew sales(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s,vipid:%s,date:%s,prod:%s|%s|%s,unit:%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                    (rkey, refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, rdate, pkey, pcode, pname, punit, rprice, pqty, ramt, rpv, rbv, self.accEmail))

        if raction == 'addnew':
            bDaTa = salesbill(
                date = ddate,
                refcstore = refstore,
                vip = dvip,
                vipid = vipid,
                vipname = vipname,
                qty = 1
                )
            bDaTa.put()
            bkey = bDaTa.key()

            for z in range(len(rprod)):
                dprod = prod.get(rprod[z])
                if not dprod:
                    continue
                zqty = rqty[z]
                bqty.append(zqty)

                rprice = dprod.price
                ramt = round(zqty*rprice, 5)
                bamt.append(ramt)
                pcode = dprod.code
                pname = dprod.name
                punit = dprod.unit
                rpvt = dprod.pvtype
                pvtname = rpvt.name
                septag = pcode if dprod.sepreport else ''
                rpv = round(ramt*rpvt.ratepv*rpvt.pvrate/10000, 5)
                rbv = round(rpv*rpvt.bvrate/100, 5)

                DaTa = sales(
                    refsalesbill = bkey,
                    refcstore = refstore,
                    vip = dvip,
                    vipid = vipid,
                    vipname = vipname,
                    date = ddate,
                    prod = dprod,
                    prodcode = pcode,
                    prodname = pname,
                    pvtypename = pvtname,
                    unit = punit,
                    qty = zqty,

                    price = rprice,
                    amount = ramt,
                    pv = rpv,
                    bv = rbv
                    )
                vipvsales.modify1(refstore, dvip, rpvt, rpv, rbv, ramt, septag)
                DaTa.put()

                rkey = DaTa.key()

                if loglog:
                    logging.debug("Admin_Log:%s %s(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,date:%s,prod:%s|%s|%s,unit:%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                    (raction, DaTa.kind(), rkey, refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, rdate, dprod, pcode, pname, punit, rprice, zqty, ramt, rpv, rbv, self.accEmail))

        bqtys = sum(bqty)
        bamts = round(sum(bamt), 5)
        bDaTa.date = ddate
        bDaTa.qty = bqtys
        bDaTa.amount = bamts
        bDaTa.put()
        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,date:%s,qty:%s,amount:%s) by %s" %
                (raction, bDaTa.kind(), bkey, refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, rdate, bqtys, bamts, self.accEmail))
        return self.write(u"success!?guid:%s;date:%s;vip:%s;vipid:%s;vipname:%s;bqty:%s;bamount:%s" %
                (bkey, rdate, rvip, vipid, vipname, bqtys, bamts))

class tiens_sales(baseHandler):
    @authorized_ajax
    def get(self):
        rjson = self.reqbool('json')
        rbill = self.req('refbill')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = sales.all().order('refsalesbill').order('-date')
            if rbill:
                refbill = salesbill.get(rbill)
                if refbill:
                    qry.filter('refsalesbill =', refbill)
            if not self.adminacc:
                qry.filter('refcstore =', self.authacc.refcstore)

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "vip":"%s", "vipname":"%s", "vipid":"%s","date":"%s","prod":"%s","pcode":"%s","pname":"%s","prodpvt":"%s","unit":"%s","price":"%s","qty":"%s","amount":"%s"}'%
                        (dT.key(), dT.key(), dT.vip.key(), dT.vipname, dT.vipid, dT.date, dT.prod.key(), dT.prodcode, dT.prodname, dT.pvtypename, dT.unit, dT.price, dT.qty, dT.amount ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authorized_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?action invalid")

        if raction == 'delete':#@todo:业绩已报单不可删除，有足够可报业绩返回才可删除
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = sales.get(rkey)
                if DaTa:
                    if DaTa.remove():
                        msg.append( "%s=" % DaTa.key() )

                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,date:%s,prod:%s|%s|%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
                            (raction, DaTa.kind(), rkey, DaTa.refcstore.key(), DaTa.refcstore.code, DaTa.refcstore.name, DaTa.vip.key(), DaTa.vip.lastname+DaTa.vip.firstname, DaTa.vip.idcard, DaTa.date, DaTa.prod.key(), DaTa.prod.code, DaTa.prod.name, DaTa.price, DaTa.qty, DaTa.amount, DaTa.pv, DaTa.bv, self.accEmail))
            if msg:
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?can not delete!")

        rdate = self.req("date")
        rvip = self.req("vip")
        rprod = self.req("prod")
        rqty = self.reqint("qty")
        rsprpt = self.reqbool("sepreport")

        if not rdate:
            return self.write('error!?date required')
        if not rvip:
            return self.write('error!?vip required')
        if not rprod:
            return self.write('error!?prod required')
        if not rqty:
            return self.write('error!?qty required')

        dvip = vip.get(rvip)
        if not dvip:
            return self.write('error!?vip invalid')
        ddate = datetime.strptime(rdate,"%Y-%m-%d").date()
        if not ddate:
            return self.write('error!?date invalid')
        dprod = prod.get(rprod)
        if not dprod:
            return self.write('error!?prod invalid')

        rprice = dprod.price
        ramt = rqty*rprice
        vipid = dvip.idcard
        vipname = '%s%s' % (dvip.lastname, dvip.firstname)
        pcode = dprod.code
        pname = dprod.name
        punit = dprod.unit
        rpvt = dprod.pvtype
        pvtname = rpvt.name
        septag = pcode if rsprpt else ''
        rpv = rpvt.pvrate*rpvt.ratepv*ramt/10000
        rbv = rpv*rpvt.bvrate/100
        refstore = self.authacc.refcstore

        if raction == 'modify':
            rkey = self.req("guid")
            rbkey = self.req('refbill')
            if not rbkey:
                return self.write("error!?refbill required")
            try:
                rbill = salesbill.get(rbkey)
            except:
                return self.write("error!?refbill not valid!")
            if not rbill:
                return self.write("error!?refbill not valid")

            DaTa = sales.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                ret,ekb = vipvsales.modify(refstore, dvip, rpvt, rpv, rbv, ramt, septag, orisale=DaTa)
                if ret:
                    DaTa.refsalesbill = rbill
                    DaTa.refcstore = refstore
                    DaTa.vip = dvip
                    DaTa.vipid = vipid
                    DaTa.vipname = vipname
                    DaTa.date = ddate
                    DaTa.prod = dprod
                    DaTa.prodcode = pcode
                    DaTa.prodname = pname
                    DaTa.pvtypename = pvtname
                    DaTa.unit = punit
                    DaTa.qty = rqty
                    DaTa.price = rprice
                    DaTa.amount = ramt
                    DaTa.pv = rpv
                    DaTa.bv = rbv

                    DaTa.put()
                else:
                    return self.write("error!?Can not be changed. $%s" % ekb)
        if raction == 'addnew':
            DaTa = sales(
                refcstore = refstore,
                vip = dvip,
                vipid = vipid,
                vipname = vipname,
                date = ddate,
                prod = dprod,
                prodcode = pcode,
                prodname = pname,
                pvtypename = pvtname,
                unit = punit,
                qty = rqty,

                price = rprice,
                amount = ramt,
                pv = rpv,
                bv = rbv
                )
            vipvsales.modify1(refstore, dvip, rpvt, rpv, rbv, ramt, septag)
            DaTa.put()

            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(refcstore:%s|%s|%s,vip:%s|%s|%s,date:%s,prod:%s|%s|%s,unit:%s,price:%s,qty:%s,amount:%s,pv:%s,bv:%s) by %s" %
            (raction, DaTa.kind(), rkey, refstore.key(), refstore.code, refstore.name, rvip, vipname, vipid, rdate, rprod, pcode, pname, punit, rprice, rqty, ramt, rpv, rbv, self.accEmail))

        return self.write(u"success!?guid:%s;date:%s;vip:%s;vipid:%s;vipname:%s;prod:%s;pcode:%s;pname:%s;prodpvt:%s;unit:%s;price:%s;qty:%s;amount:%s" %
                (rkey, rdate, rvip, vipid, vipname, rprod, pcode, pname, pvtname, punit, rprice, rqty, ramt))

class tiens_accounts(baseHandler):
    @authadmin_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = admin.all()

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "isadmin":"%s", "role":"%s", "rolename":"%s","name":"%s","refcstore":"%s","refcsname":"%s","email":"%s","admin":"%s"}'%
                        (dT.key(), dT.key(), 'yes' if dT.isadmin else 'no', dT.role.key() if dT.role else '', dT.role.name if dT.role else '', dT.name, dT.refcstore.key() if dT.refcstore else '', dT.refcstore.name if dT.refcstore else u'无', dT.email, '&#10004;' if dT.isadmin else '&#10008;' ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authadmin_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?invalid action")

        if raction == 'delete':
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = admin.get(rkey)
                if DaTa:
                    if not DaTa.ownstore.count(2):#有下级类别，或有该类别产品时不能删除
                        msg.append( "%s=" % DaTa.key() )
                        DaTa.delete()
                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(isadmin:%s,email:%s,name:%s,role:%s,refcstore:%s) by %s" %
                            (raction, DaTa.kind(), rkey, DaTa.isadmin, DaTa.email, DaTa.name, (str(DaTa.role.key())+'|'+DaTa.role.name) if DaTa.role else None, (str(DaTa.refcstore.key())+'|'+DaTa.refcstore.code+'|'+DaTa.refcstore.name) if DaTa.refcstore else None, self.accEmail))
            if msg:
                #reset cache
                #getdata(admin, order=["email"], limit=50, reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?in use")

        radmin = self.reqbool("isadmin")
        remail = self.req("email").lower()
        rrole = self.req("role")
        rname = self.req("name")
        rref = self.req("refcstore")

        if not remail:
            return self.write('error!?email required')
        if not rname:
            return self.write('error!?name required')
        if not rrole:
            return self.write('error!?role required')
        if not rref:
            return self.write('error!?cstore required')

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = admin.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                DaTa.isadmin = radmin
                DaTa.refcstore = cstore.get(rref) if rref else None
                DaTa.role = role.get(rrole) if rrole else None
                DaTa.name = rname
                DaTa.email = remail

                DaTa.put()

        if raction == 'addnew':
            Ydata = admin.all().filter('email =', remail).count(2)
            if Ydata:
                return self.write('error!?email exist')

            DaTa = admin(
                    isadmin = radmin,
                    refcstore = cstore.get(rref) if rref else None,
                    role = role.get(rrole) if rrole else None,
                    name = rname,
                    email = remail
                    )
            DaTa.put()

            rkey = DaTa.key()

        if loglog:
            logging.debug("Admin_Log:%s %s(key:%s) detail(isadmin:%s,email:%s,name:%s,role:%s,refcstore:%s) by %s" %
            (raction, DaTa.kind(), rkey, radmin, remail, rname, rrole, rref, self.accEmail))

        #reset cache
        #getdata(admin, order=["email"], limit=50, reset=True)

        refcsname = DaTa.refcstore.name if DaTa.refcstore else u'无'
        rolename = DaTa.role.name if DaTa.role else u'无'
        return self.write(u"success!?guid:%s;isadmin:%s;role:%s;rolename:%s;name:%s;refcstore:%s;refcsname:%s;email:%s;admin:%s" %
            (rkey, 'yes' if radmin else 'no', rrole if rrole else '', rolename, rname, rref if rref else '', refcsname, remail, '&#10004;' if radmin else '&#10008;'))

class tiens_roles(baseHandler):
    @authadmin_ajax
    def get(self):
        rjson = self.reqbool('json')

        op = []
        if rjson:
            rlimit = self.reqint('pagesize')
            rpaging = self.reqint('paging')

            qry = role.all()

            total, pagecount, pageindex, daTa = paging(query=qry, limit=rlimit).fetch(rpaging)
            if daTa:
                for dT in daTa:
                    op.append(u'"%s": {"guid":"%s", "rolename":"%s","tpurl":"%s"}'%
                        (dT.key(), dT.key(), dT.name, dT.tpurl ))
            self.write("success!?total:%s;pagecount:%s;paging:%s`$!`{%s}" % (total, pagecount, pageindex, ','.join(op)))
        else:
            self.write("error!?action invalid!")

    @authadmin_ajax
    def post(self):
        raction = self.req("action")

        if raction not in formaction:
            return self.write("error!?invalid action")

        if raction == 'delete':
            keys = self.reqall("guid")
            msg = []
            for rkey in keys:
                DaTa = role.get(rkey)
                if DaTa:
                    if not DaTa.roleaccount.count(2):#有不能删除
                        msg.append( "%s=" % DaTa.key() )
                        DaTa.delete()
                        if loglog:
                            logging.warning("Admin_Log:%s %s(key:%s) detail(name:%s,tpurl:%s) by %s" %
                            (raction, DaTa.kind(), rkey, DaTa.name, DaTa.url, self.accEmail))
            if msg:
                #reset cache
                #getdata(role, limit=50, reset=True)
                return self.write("success!?%s" % '&'.join(msg))
            else:
                return self.write("error!?in use")

        rname = self.req("rolename").upper()
        rurl = self.req("tpurl").lower()

        if not rname:
            return self.write('error!?name required')
        if not rurl:
            return self.write('error!?role required')

        if raction == 'modify':
            rkey = self.req("guid")
            DaTa = role.get(rkey)
            if not DaTa:
                return self.write("error!?id not valid")
            else:
                DaTa.name = rname
                DaTa.tpurl = rurl

                DaTa.put()

        if raction == 'addnew':
            Ydata = role.all().filter('name =', rname).count(2)
            if Ydata:
                return self.write('error!?name exist')

            DaTa = role(
                    name = rname,
                    tpurl = rurl
                    )
            DaTa.put()

            rkey = DaTa.key()

        logging.debug("Admin_Log:%s %s(key:%s) detail(name:%s,tpurl:%s) by %s" %
            (raction, DaTa.kind(), rkey, rname, rurl, self.accEmail))

        #reset cache
        #getdata(role, limit=50, reset=True)

        return self.write(u"success!?guid=%s&rolename=%s&tpurl=%s" %
            (rkey, rname, rurl))

class tiens_sysforms(baseHandler):
    @authorized_ajax
    def get(self):
        self.redirect("/tiens")

    @authadmin_ajax
    def post(self):
        ref = self.req("refapp")
        fid = self.req("formid")
        actionurl = self.req("formaction")
        styleclass = self.req("formstyle")
        formtitle = self.req("formtitle")
        hasfile = self.reqbool("formfile")
        formethod = self.req("formethod")
        action = self.req("action")

        DaTa = sysforms(
            refapp=ref,
            formid = fid,
            actionurl = actionurl,
            formethod = formethod,
            styleclass = styleclass,
            encrypt = "application/x-www-form-urlencoded" if hasfile else "multipart/form-data",
            formtitle = formtitle
            )
        DaTa.put()

        self.redirect("/tiens")

class tiens_main(baseHandler):
    @requires_admin
    def get(self):
        user = users.get_current_user()
        userinfo = ("<span>%s</span> | <a href=\"/index\">返回首页</a> | <a href=\"/tstore\">店管理</a> | <a href=\"%s\">退出登录</a>" %
                    ( user.nickname(), users.create_logout_url("/") ) )

        pvtypes = pubdata(pvtype, order=["-pvrate","-bvrate","code"])#pubpvtypes-pvrate-bvrate
        pcls = pubdata(prodcls, order=["code"])#pubprodclscode
        roles = getdata(role, limit=20)

        optcs_noab = memcache.get('optcs_noab')
        optcscb = memcache.get('optcscb')
        optcsaa = memcache.get('optcsaa')
        if (not optcscb) or (not optcsaa) or (not optcs_noab):
            def cbcstore (cs):
                return cs.type == 'cb'
            def aacstore (cs):
                return cs.type == 'aa'
            optcs_noab = cstore.all().filter('type !=', 'ab').fetch(1000)
            optcscb = filter(cbcstore, optcs_noab)
            optcsaa = filter(aacstore, optcs_noab)
            memcache.set('optcs_noab', optcs_noab, 2548800)
            memcache.set('optcscb', optcscb, 2548800)
            memcache.set('optcsaa', optcsaa, 2548800)

        tab = self.req('tab')

        template_values={"userinfo": userinfo,
            'isotime':(datetime.now()+timedelta(hours=+8)),
            "pvtypes": pvtypes,
            'optcmpnyab':optcs_noab,
            'optcmpny':optcscb,
            'optstore':optcsaa,
            "pclass": pcls,
            "roles": roles,
            'imgsurl':imagesurl,
            "app_id": APP_ID
            }

        self.render('template/tiens.html', template_values)

app = webapp.WSGIApplication(
        [
        ('/tiens/{0,1}', tiens_main),
        ('/tiens/setup', tiens_setup),
        ('/tiens/cstore', tiens_cstore),
        ('/tiens/vip', tiens_vips),
        ('/tiens/prodclass', tiens_pclass),
        ('/tiens/pvtype', tiens_pvtype),
        ('/tiens/prods', tiens_prods),
        ('/tiens/po', tiens_po),
        ('/tiens/stock', tiens_stocks),
        ('/tiens/sales', tiens_sales),
        ('/tiens/salesbill', tiens_salesbill),
        ('/tiens/pvreport', tiens_pvreport),
        ('/tiens/vipspv', tiens_vipspv),
        ('/tiens/approvepvsall', tiens_approvepvsall),
        ('/tiens/cstorepv', tiens_cstorepv),
        ('/tiens/admins', tiens_accounts),
        ('/tiens/roles', tiens_roles),
        ('/tiens/resform', tiens_sysforms),
        ('/tiens/move2gs', tiens_move2gs),

        ('.*',Error404),
        ],
        debug=True)
